<?php

namespace liketp\route;

use liketp\Request;

abstract class Rule
{
    protected $domain = '';
    protected $method = '';

    protected $name = '';
    protected $rule = '';
    protected $route = '';

    protected $router = null;
    protected $parent = null;

    protected $vars = [];
    protected $option = [];
    protected $pattern = [];

    protected $mergeOptions = [];


    //------------------------------------------------ external methods
    public function name(string $name)
    {
        $this->name = $name;
    }

    public function option(array $options)
    {
        $this->option = array_merge($this->option, $options);
        return $this;
    }

    public function pattern($pattern)
    {
        $this->pattern = array_merge($this->pattern, $pattern);
        return $this;
    }

    public function method(string $method)
    {
        return $this->setOption('method', strtolower($method));
    }

    public function domain(string $domain)
    {
        return $this->domain = $domain;
    }

    public function completeMatch(bool $flag = true)
    {
        return $this->setOption('complete_match', $flag);
    }

    public function prefix(string $prefix = '')
    {
        return $this->setOption('prefix', $prefix);
    }

    public function append(array $append = [])
    {
        return $this->setOption('append', $append);
    }


    //------------------------------------------------ enternal methods
    public function setParent($group)
    {
        $this->parent = $group;
        return $this;
    }

    public function getDomain()
    {
        return $this->domain;
    }

    public function getPattern(string $varName = '', string $default = '')
    {
        if ($varName == '') {
            $parentPattern = $this->parent ? $this->parent->getPattern() : [];
            return array_merge($parentPattern, $this->pattern);
        }
        if (isset($this->pattern[$varName])) return $this->pattern[$varName];
        if ($this->parent) return $this->parent->getPattern($varName, $default);
        return $default;
    }

    public function setOption(string $name, $value)
    {
        $this->option[$name] = $value;
        return $this;
    }

    public function getOption(string $name = '', $default = '')
    {
        $option = $this->option;

        if ($this->parent) {
            $parentOption = $this->parent->getOption();
            $option = array_merge($parentOption, $option);
        }

        if (empty($name)) return $option;

        return $option[$name] ?? $default;
    }

    public function getPrefix()
    {
        $prefix = $this->getOption('prefix', '');
        $parentPrefix = $this->parent ? $this->parent->getPrefix() : '';
        return $parentPrefix . $prefix;
    }

    public function getAppend()
    {
        $append = $this->getOption('append', []);
        $parentAppend = $this->parent ? $this->parent->getAppend() : [];
        return array_merge($parentAppend, $append);
    }


    //------------------------------------------------ protected
    protected function checkOption(array $option, Request $request): bool
    {
        // method
        $method = $request->method();
        if (!empty($option['method'])) {
            if ($method == 'OPTIONS') {
                if ($this->isAutoOptions() == false) {
                    return false;
                }
            } else {
                if (is_string($option['method']) && false === stripos($option['method'], $method)) {
                    return false;
                }
            }
        }

        // ajax

        // ext

        // domain

        // https

        // filter

        return true;
    }
}
